package com.gupao.gupaoeduvippattern.javaBase.a4fanshe;

import com.gupao.gupaoeduvippattern.javaBase.bean.Apple;
import com.gupao.gupaoeduvippattern.javaBase.bean.StudentDO;
import com.gupao.gupaoeduvippattern.javaBase.bean.TestBean;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 反射的案例演示
 *
 * @author Administrator
 * @date 2020-12-02 23:19
 */
public class Demo1 {


    @Test
    public void test5(){
        testString1("1","2","3");
        testString1();
//        testString1(null);    //会报错NPE(java.lang.NullPointerException )

        testString2(new String[]{"aa","bb"});
    }


    public void testString1(String... strings){
        //sout
        System.out.println("=========testString1===============");
        for(String str : strings){
            System.out.println(str);
        }
    }

    public void testString2(String[] strings){
        System.out.println("=========testString2===============");
        for(String str : strings){
            System.out.println(str);
        }
    }


    @Test
    public void test4() throws IllegalAccessException, InstantiationException,
            NoSuchMethodException, InvocationTargetException {
//        通过反射创建类对象
        Class<StudentDO> clz = StudentDO.class;
        StudentDO studentDO = clz.newInstance();

        //2
        Constructor<StudentDO> constructor = clz.getConstructor();
        StudentDO studentDO2 = constructor.newInstance();
        System.out.println(studentDO2);

        //3
        Constructor<StudentDO> constructor3 = clz.getConstructor(String.class, String.class);
        StudentDO studentDO3 = constructor3.newInstance("张三", "123456");
        System.out.println(studentDO3);

        //4
        System.out.println("=================4================");
        Field[] fields = clz.getFields();
        for(Field field : fields){
            System.out.println(field);
        }

        System.out.println("===============4-2================");
        Field[] declaredFields = clz.getDeclaredFields();
        for(Field field : declaredFields){
            System.out.println(field);
        }



    }


    public void test3() throws ClassNotFoundException {
        /*
        * 在 JDK 中，反射相关的 API 可以分为下面几个方面：
        * 获取反射的 Class 对象、通过反射创建类对象、通过反射获取类属性方法及构造器。
        * */
        //获取反射中的Class对象(获取类对象的三种方式)
        //第一种，使用 Class.forName 静态方法。当你知道该类的全路径名时，你可以使用该方法获取 Class 类对象
        Class<?> clz = Class.forName("java.lang.String");

//        第二种，使用 .class 方法。 这种方法只适合在编译前就知道操作的 Class。
        Class clz2 = String.class;


//        第三种，使用类对象的 getClass() 方法。
        String str = "123456";
        Class<? extends String> clz3_1 = str.getClass();

        String str2 = new String("abcdefg");
        Class<? extends String> clz3_2 = str2.getClass();


    }


    @Test
    public void test2() throws ClassNotFoundException, NoSuchMethodException, 
            IllegalAccessException, InvocationTargetException, InstantiationException {
        //1、正射
        Apple apple = new Apple();  //直接初始化，「正射」
        apple.setPrice(4);
        System.out.println(apple);

        /*2、反射。
         *   反射则是一开始并不知道我要初始化的类对象是什么，自然也无法使用 new 关键字来创建对象了。
         *  反射就是在运行时才知道要操作的类是什么，并且可以在运行时获取类的完整构造，并调用对应的方法。
         */
        //获取类的class对象实例
        Class<?> clz = Class.forName("com.gupao.gupaoeduvippattern.javaBase.bean.Apple");
        Method setPriceMethod = clz.getMethod("setPrice", Integer.class);
//        根据 Class 对象实例获取 Constructor 对象
        Constructor<?> constructor = clz.getConstructor();
//        使用 Constructor 对象的 newInstance 方法获取反射类对象
        Object object = constructor.newInstance();
        setPriceMethod.invoke(object, 4);

        //
        Method getPriceMethod = clz.getMethod("getPrice");
        System.out.println("Apple Price:" + getPriceMethod.invoke(object));

    }

    @Test
    public void test1_2(){
        TestBean tb = new TestBean();
        System.out.println(tb);
    }


    @Test
    public void test1(){
        //1、基本反射技术、getClass()
        String name = "abcdefg";
        Class<? extends String> c1 = name.getClass();
        System.out.println(c1.getName());  // java.lang.String

        //2、Class.forName()
        String name2 = "java.lang.String";
        Class<?> c2 = null;
        try {
            c2 = Class.forName(name2);
            Class<?> superclass2 = c2.getSuperclass();
            System.out.println(c2 +"," +superclass2);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //3、
        Class cc1 = Boolean.TYPE;
        Class cc2 = Byte.TYPE;
        Class cc3 = Float.TYPE;
        Class cc4 = Double.TYPE;

    }


}
